package com.gdut.huayan.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gdut.huayan.constant.AliyunConstant;
import com.gdut.huayan.dao.ConversionActivityMapper;
import com.gdut.huayan.dao.ConversionMapper;
import com.gdut.huayan.entity.dto.PageQuery;
import com.gdut.huayan.entity.po.Conversion;
import com.gdut.huayan.entity.po.ConversionActivity;
import com.gdut.huayan.entity.vo.SmsReserveVo;
import com.gdut.huayan.service.ConversionService;
import com.gdut.huayan.service.exception.BaseException;
import com.gdut.huayan.utils.AliyunUtils;
import com.gdut.huayan.utils.SecurityUtils;
import com.gdut.huayan.utils.StringUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.time.LocalDateTime;
import java.util.List;

@Service
public class ConversionServiceImpl extends ServiceImpl<ConversionMapper, Conversion> implements ConversionService {

    @Autowired
    private ConversionActivityMapper conversionActivityMapper;

    @Override
    public boolean save(Conversion conversion) {
        ConversionActivity conversionActivity = conversionActivityMapper.selectById(conversion.getActivityId());
        if (conversionActivity.getType() != 3 && !conversionActivity.getType().equals(conversion.getType())) {
            throw new BaseException(4000, "皈依类型错误");
        }
        if (LocalDateTime.now().isAfter(conversionActivity.getEndTimeByType(conversion.getType())) ||
                LocalDateTime.now().isBefore(conversionActivity.getStartTimeByType(conversion.getType()))) {
            throw new BaseException(4000, "不在活动时间内不能皈依");
        }
        QueryWrapper<Conversion> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", SecurityUtils.getUserIdNumber());
        queryWrapper.ne("status",4);
        List<Conversion> hasConversionList = baseMapper.selectList(queryWrapper);
        boolean isNotGuiYi = true;
        if (hasConversionList != null) {
            for (Conversion hasConversion : hasConversionList) {
                if (conversion.getType() == 1) {
                    //判断之前有没有三皈或五戒
                    judgeConversion(hasConversion, conversionActivity.getId());
                } else {
                    if (hasConversion.getType() == 2) {
                        //判断之前有没有五戒
                        judgeConversion(hasConversion, conversionActivity.getId());
                    } else if (hasConversion.getStatus() == 3 && hasConversion.getType() == 1) {
                        //判断是否有三皈
                        isNotGuiYi = false;
                    }
                }
            }
        }
        if (conversion.getType() == 2 && isNotGuiYi) {
            throw new BaseException(4000, "请先皈依");
        }
        conversion.setUserId(SecurityUtils.getUserIdNumber());
        conversion.setStatus(1);
        conversion.setCreateTime(LocalDateTime.now());
        baseMapper.insert(conversion);
        sendMessage(conversion);
        return true;
    }

    //发送短信
    private void sendMessage(Conversion conversion) {
        //手机号国区校验
        String phone = conversion.getPhone();
        if (StringUtils.isNotEmpty(conversion.getPhoneCountry())) {
            //手机号码国区校验
            phone = conversion.getPhoneCountry() + phone;
        }
        //SmsReserveVo短信内容装配
        SmsReserveVo reserve = new SmsReserveVo();
        reserve.setCode(conversion.getNumber());
        AliyunUtils.sendSMS(phone,
                AliyunConstant.SIGN_NAME,
                AliyunConstant.TEMPLATE_CODE,
                JSONObject.toJSONString(reserve));

    }



    /**
     * @param hasConversion 用户已参加的三皈五戒活动表单 status={1,2,3}
     * @param activityId    用户当前申请的活动id
     */
    private void judgeConversion(Conversion hasConversion, Long activityId) {
        if (hasConversion.getStatus() == 3) {
            //已参加
            throw new BaseException(4000, "不可重复皈依");
        } else {
            //申请中或未参加要看看是不是之前申请的(即是不是本次活动申请的)
            if (hasConversion.getActivityId().equals(activityId)) {
                throw new BaseException(4000, "已有申请中的三皈五戒，不可重复皈依");
            }
        }
    }

    @Override
    public PageInfo<Conversion> getByActivityId(Long activityId, Integer status, PageQuery pageQuery) {
        PageHelper.startPage(pageQuery.getPage(), pageQuery.getSize());
        QueryWrapper<Conversion> queryWrapper = new QueryWrapper<>();
        if (activityId != null) {
            queryWrapper.eq("activity_id", activityId);
        }
        if (status != null) {
            queryWrapper.eq("status", status);
        }
        if (StringUtils.isNotEmpty(pageQuery.getSearch())) {
            queryWrapper.like("phone", "%" + pageQuery.getSearch() + "%");
        }
        if ("ASC".equals(pageQuery.getOrder())) {
            queryWrapper.orderByAsc(pageQuery.getOrderKey().split(";"));
        }
        if ("DESC".equals(pageQuery.getOrder())) {
            queryWrapper.orderByDesc(pageQuery.getOrderKey().split(";"));
        }
        PageInfo<Conversion> result = new PageInfo<>(baseMapper.selectList(queryWrapper));
        fillConversionName(result.getList());
        result.getList().forEach(c -> c.setNumber(c.getNumber()));
        return result;
    }


    @Override
    public ConversionActivity get() throws UnsupportedEncodingException {
        QueryWrapper<ConversionActivity> wrapper = new QueryWrapper<>();
        wrapper .ge("san_gui_end_time", LocalDateTime.now())
                .le("san_gui_start_time", LocalDateTime.now())
                .or()
                .ge("wu_jie_end_time", LocalDateTime.now())
                .le("wu_jie_start_time", LocalDateTime.now())
                .and(i -> i.eq("status", 1))
                .orderByDesc("id")
                .last("limit 1");
        ConversionActivity one = conversionActivityMapper.selectOne(wrapper);
        return one;
    }

    @Override
    public PageInfo<Conversion> getUserConversion(PageQuery pageQuery, Integer status) {
        PageHelper.startPage(pageQuery.getPage(), pageQuery.getSize());
        QueryWrapper<Conversion> queryWrapper = new QueryWrapper<>();
        if (status != null) {
            queryWrapper.eq("status", status);
        }
        queryWrapper.eq("user_id", SecurityUtils.getUserIdNumber());
        if ("ASC".equals(pageQuery.getOrder())) {
            queryWrapper.orderByAsc(pageQuery.getOrderKey().split(";"));
        }
        if ("DESC".equals(pageQuery.getOrder())) {
            queryWrapper.orderByDesc(pageQuery.getOrderKey().split(";"));
        }
        PageInfo<Conversion> result = new PageInfo<>(baseMapper.selectList(queryWrapper));
        fillConversionName(result.getList());
        result.getList().forEach(c -> c.setNumber(c.getNumber()));
        return result;
    }

    @Override
    public Conversion selectByNumber(String number) {
        Conversion conversion = baseMapper.selectById(StringUtils.reverseNumber(number));
        Conversion updateConversion = new Conversion();
        updateConversion.setId(conversion.getId());
        updateConversion.setStatus(3);
        return updateConversion;
    }

    @Override
    public boolean updateById(Conversion conversion) {
        conversion.setImageFileId(null);
        //判断是否是管理员，判断能否修改status
        boolean isNotAdmin = true;
        for (GrantedAuthority role : SecurityContextHolder.getContext().getAuthentication().getAuthorities()) {
            if ("SUPER_ADMIN".equals(role.getAuthority())) {
                isNotAdmin = false;
            }
        }
        Conversion sqlConversion = baseMapper.selectById(conversion.getId());
        if (isNotAdmin) {
            //如果不是管理员则不能修改状态
            conversion.setStatus(null);
            if (sqlConversion.getStatus() != 1) {
                //如果表单已经经过审核且不是管理员进行操作则不能修改
                throw new BaseException(4000, "已被管理员审核，无法修改");
            }
        }
        /*if (conversion.getStatus() != null) {
            //管理员审核
            switch (sqlConversion.getStatus()) {
                case 1:
                    if (conversion.getStatus() == 3) {
                        throw new BaseException(4000, "输入的皈依状态错误");
                    }
                    break;
                case 2:
                    if (conversion.getStatus() == 1 || conversion.getStatus() == 4) {
                        throw new BaseException(4000, "输入的皈依状态错误");
                    }
                    break;
                default:
                    //status = 3 or 4
                    throw new BaseException(4000, "无法改变当前皈依状态");
            }
        }*/
        return super.updateById(conversion);
    }

    @Override
    public boolean removeById(Serializable id) {
        Integer count = new LambdaQueryChainWrapper<>(baseMapper)
                .eq(Conversion::getActivityId, id)
                .count();
        if (count > 0) {
            throw new BaseException(4000, "该活动已有信众参加，无法删除");
        }
        return super.removeById(id);
    }

    private void fillConversionName(List<Conversion> conversionList) {
        if (conversionList != null) {
            for (Conversion conversion : conversionList) {
                StringBuilder sb = new StringBuilder("释");
                ConversionActivity conversionActivity = conversionActivityMapper.selectById(conversion.getActivityId());
                sb.append(conversionActivity.getFrontName());
                sb.append(conversion.getName().substring(conversion.getName().length() - 1));
                conversion.setConversionName(sb.toString());
            }
        }
    }
}
